package com.yyy.tcc.service.impl;

import com.yyy.tcc.service.TransferService;
import com.yyy.tcc.dao.AccountDao;
import com.yyy.tcc.dao.TransferTransactionDao;
import com.yyy.tcc.entity.TransferTransaction;
import com.yyy.common.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.sql.SQLException;
import javax.sql.DataSource;

public class TransferServiceImpl implements TransferService {
    private static final Logger log = LoggerFactory.getLogger(TransferServiceImpl.class);

    private final AccountDao accountDao;
    private final TransferTransactionDao transactionDao;

    public TransferServiceImpl(DataSource dataSource) {
        this.accountDao = new AccountDao(dataSource);
        this.transactionDao = new TransferTransactionDao(dataSource);
    }

    @Override
    public boolean transfer(String transactionId, String fromUserId, String toUserId, BigDecimal amount) {
        try {
            // TCC分布式事务处理
            if (try_(transactionId, fromUserId, toUserId, amount)) {
                if (confirm(transactionId)) {
                    return true;
                }
                cancel(transactionId);
            }
            return false;
        } catch (Exception e) {
            cancel(transactionId);
            throw new BusinessException("TCC-001", "转账失败: " + e.getMessage());
        }
    }

    @Override
    public boolean try_(String transactionId, String fromUserId, String toUserId, BigDecimal amount) {
        try {
            // 1. 创建事务记录
            if (!transactionDao.createTransaction(transactionId, fromUserId, toUserId, amount)) {
                throw new BusinessException("TCC-002", "创建事务记录失败");
            }

            // 2. 尝试冻结转出账户金额
            if (!accountDao.tryFreeze(fromUserId, amount)) {
                throw new BusinessException("TCC-003", "账户余额不足");
            }

            return true;
        } catch (Exception e) {
            log.error("Try阶段失败", e);
            return false;
        }
    }

    @Override
    public boolean confirm(String transactionId) {
        try {
            TransferTransaction transaction = transactionDao.getByTransactionId(transactionId);
            if (transaction == null) {
                throw new BusinessException("TCC-004", "事务不存在");
            }

            // 确认转账
            if (!accountDao.confirm(transaction.getFromUserId(),
                                  transaction.getToUserId(),
                                  transaction.getAmount())) {
                throw new BusinessException("TCC-005", "确认转账失败");
            }

            transactionDao.updateStatus(transactionId, "CONFIRMED");
            return true;
        } catch (Exception e) {
            log.error("Confirm阶段失败", e);
            return false;
        }
    }

    @Override
    public boolean cancel(String transactionId) {
        try {
            TransferTransaction transaction = transactionDao.getByTransactionId(transactionId);
            if (transaction == null) {
                return true; // 事务不存在，视为已取消
            }

            // 解冻资金
            if (!accountDao.cancel(transaction.getFromUserId(), transaction.getAmount())) {
                throw new BusinessException("TCC-006", "取消转账失败");
            }

            transactionDao.updateStatus(transactionId, "CANCELLED");
            return true;
        } catch (Exception e) {
            log.error("Cancel阶段失败", e);
            return false;
        }
    }

    @Override
    public AccountDao getAccountDao() {
        return accountDao;
    }
}
